package org.apache.ibatis.executor;

import org.apache.ibatis.cache.CacheKey;
import org.apache.ibatis.cursor.Cursor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.transaction.Transaction;

import java.sql.SQLException;
import java.util.List;

/**
 * Executor 是MyBatis的核心接口之一，其中定义了数据库操作的基本方法。
 * 在实际应用中经常涉及的SqlSession接口的功能，都是基于Executor接口实现的
 *
 * @author Clinton Begin
 */
public interface Executor {

    ResultHandler NO_RESULT_HANDLER = null;

    /**
     * 执行update、insert, delete三种类型的SQL语句
     *
     * @param ms
     * @param parameter
     * @return
     * @throws SQLException
     */
    int update(MappedStatement ms, Object parameter) throws SQLException;

    /**
     * 执行select类型的SQL语句，返回结果对象列表
     *
     * @return
     * @throws SQLException
     */
    <E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey cacheKey, BoundSql boundSql) throws SQLException;

    /**
     * 执行select类型的SQL语句，返回结果对象列表
     * @return
     * @throws SQLException
     */
    <E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException;

    /**
     * 执行select类型的SQL语句，返回游标对象
     *
     * @return
     * @throws SQLException
     */
    <E> Cursor<E> queryCursor(MappedStatement ms, Object parameter, RowBounds rowBounds) throws SQLException;

    /**
     * 批量执行SQL语句
     * 主要是针对批处理多条SQL语句的，它会调用doFlushStatements()这个基本方法处理Executor中缓存的多条SQL语句。
     * 在BaseExecutor.commit()、rollback()等方法中都会首先调用flushStatements()方法，然后再执行相关事务操作
     *
     * @return
     * @throws SQLException
     */
    List<BatchResult> flushStatements() throws SQLException;

    /**
     * 提交事务
     *
     * @param required
     * @throws SQLException
     */
    void commit(boolean required) throws SQLException;

    /**
     * 回滚事物
     *
     * @param required
     * @throws SQLException
     */
    void rollback(boolean required) throws SQLException;

    /**
     * 创建缓存中用到的CacheKey对象
     *
     * @param ms
     * @param parameterObject
     * @param rowBounds
     * @param boundSql
     * @return
     */
    CacheKey createCacheKey(MappedStatement ms, Object parameterObject, RowBounds rowBounds, BoundSql boundSql);

    /**
     * 根据CacheKey对象查找缓存
     *
     * @param ms
     * @param key
     * @return
     */
    boolean isCached(MappedStatement ms, CacheKey key);

    /**
     * 清空一级缓存
     */
    void clearLocalCache();

    /**
     * 延迟加载一级缓存中的数据
     *
     * @param ms
     * @param resultObject
     * @param property
     * @param key
     * @param targetType
     */
    void deferLoad(MappedStatement ms, MetaObject resultObject, String property, CacheKey key, Class<?> targetType);

    /**
     * 获取事务对象
     *
     * @return
     */
    Transaction getTransaction();

    /**
     * 关闭Executor对象
     *
     * @param forceRollback
     */
    void close(boolean forceRollback);

    /**
     * 检测Executor是否已关闭
     *
     * @return
     */
    boolean isClosed();

    /**
     *
     * @param executor
     */
    void setExecutorWrapper(Executor executor);

}
